package cn.ffcs.contract.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.URLEncoder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.echoice.Constants;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import cn.ffcs.base.web.BaseAction;
import cn.ffcs.base.web.PageControl;
import cn.ffcs.bpmpvc.services.bean.ConfigBean;
import cn.ffcs.common.model.Attach;
import cn.ffcs.common.service.AttachService;
import cn.ffcs.contract.model.ActContract;
import cn.ffcs.contract.model.ContractInfo;
import cn.ffcs.contract.model.ContractRecord;
import cn.ffcs.contract.model.ContractRemind;
import cn.ffcs.contract.model.ContractUpload;
import cn.ffcs.contract.model.VContractInfo;
import cn.ffcs.contract.service.ContractInfoService;
import cn.ffcs.contract.service.ContractRecordService;
import cn.ffcs.contract.service.ContractRemindService;
import cn.ffcs.contract.service.ProjectService;
import cn.ffcs.organ.model.OrgRelaPerson;
import cn.ffcs.organ.service.OrgRelaPersonService;
import cn.ffcs.security.model.User;
import cn.ffcs.security.model.UserResource;
import cn.ffcs.security.web.UserContext;
import cn.ffcs.system.dict.model.Dict;
import cn.ffcs.system.dict.model.DictType;
import cn.ffcs.system.dict.service.DictService;
import cn.ffcs.system.dict.service.DictTypeService;
import cn.ffcs.util.context.ApplicationContextUtil;
import cn.ffcs.util.converter.DateUtil;
import cn.ffcs.util.properties.PropertiesUtil;

import com.opensymphony.xwork2.ActionContext;

/**
 * 
 * 流程action层，实现页面业务逻辑<br/> <table>
 * <tr>
 * <td>负责人/principal: </td>
 * <td colspan="2">pany</td>
 * <tr>
 * <td>修改记录/revision:</td>
 * <td colspan="2"></td>
 * </tr>
 * <tr>
 * <td>日期:</td>
 * <td>修改人:</td>
 * <td>修改说明:</td>
 * </tr>
 * <tr>
 * <td></td>
 * <td></td>
 * <td></td>
 * </tr>
 * </table>
 * 
 * @author pany
 * @version $Id$
 */

public class ContractInfoAction<P extends ContractInfo> extends BaseAction<P> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final int BUFFER_SIZE = 512 * 1024;
	/** 业务POJO * */
	private P contractInfo;
	/** 业务POJO * */
	private ContractRecord contractRecord;
	/** 附件列表数据 * */
	private List<Attach> attachs;

	private List<ContractUpload> contractUploads;
	/** 数据字典服务 * */
	private DictService dictService;
	/** 数据字典类型服务 * */
	private DictTypeService dictTypeService;
	/** 附件服务 * */
	private AttachService attachService;
	/** 附件上传 * */
	private List<File> uploads;
	/** 上传附件名称 * */
	private List<String> fileNames;
	private List<String> uploadContentTypes;
	/** 处理意见服务 * */
	private ContractRecordService contractRecordService;
	/** 处理意见数据集 * */
	private List<ContractRecord> contractRecords;
	/** 处理意见数据集 * */
	private List<Dict> contractTypes;
	/** 发送消息人数据集 * */
	private List processors;
	/** 合同会签转向标示 * */
	private String flag;
	/** 人员组织服务 * */
	private OrgRelaPersonService orgRelaPersonService;
	/** 合同管理系统接口 * */
	private ActContract actContract;
	/** 附件上传 * */
	private File file1;
	/** 附件上传 * */
	private File file2;

	private ContractRemindService contractRemindService;
	@SuppressWarnings("unchecked")
	private ContractInfoService contractInfoService;
	private ProjectService projectService;
	private ConfigBean configBean;

	public ConfigBean getConfigBean() {
		return configBean;
	}

	public void setConfigBean(ConfigBean configBean) {
		this.configBean = configBean;
	}

	/**
	 * 合同导入 
	 * @return
	 */
	public String into() {
		//		getContractInfoService().impDataFromExcel("d:/11.xls");
		getContractInfoService().impDataFromExcel("F:/ht/t_ht_lib.xls");
		return null;
	}

	/**
	 * 根据关键值获取实体数据
	 * 
	 * @return
	 */
	public String listFirstPic() {

		return SUCCESS;
	}

	/**
	 * 根据关键值获取实体数据
	 * 
	 * @return
	 */
	public String saveFirstPic() {
		// 保存附件
		if (file1 != null) {
			saveFirstPic(file1, "cphdzx_home_10.gif");
		}
		if (file2 != null) {
			saveFirstPic(file2, "cphdzx_home_26.gif");
		}
		return SUCCESS;
	}

	/**
	 * 根据关键值获取实体数据//保存文件？
	 * 
	 * @return
	 */
	public void saveFirstPic(File file, String fileName) {
		try {
			String contextPath = ServletActionContext.getServletContext().getRealPath("/");
			String saveDirectory = contextPath + PropertiesUtil.readValue("/poc-ftp.properties", "ftp.first.path");
			// 保存绝对路径
			String saveFilePath = saveDirectory + fileName;
			FileUtils.copyFile(file, new File(saveFilePath));
			FileUtils.forceDelete(file);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return;
	}

	/**
	 * 
	 * 初始化业务数据
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String init() {
		HttpServletRequest request = ApplicationContextUtil.getHttpServletRequest();
		String dtKey = "CONTRACT_TYPE";
		Criterion condDt = Restrictions.eq("keyValue", dtKey);
		List<DictType> ldt = this.dictTypeService.findBy(condDt);

		if (ldt != null && ldt.size() > 0) {
			DictType dictType = (DictType) ldt.get(0);
			Criterion cond = Restrictions.eq("dictType.id", dictType.getId());
			contractTypes = dictService.findBy(cond);
		} else {
			contractTypes = new ArrayList<Dict>();
		}

		if (contractInfo != null && contractInfo.getId() != null) {
			Criterion cond1 = Restrictions.eq("refEntity", contractInfo.getClass().getName());
			Criterion cond2 = Restrictions.eq("refEntityID", contractInfo.getId().toString());
			Criterion condAttach = Restrictions.and(cond1, cond2);
			attachs = attachService.findBy(condAttach);
		}

		// 取新的附件表数据
		if (contractInfo != null && contractInfo.getId() != null) {
			List<ContractUpload> contractUploads = getContractInfoService().getContractInfoDAO().listContractUpload(contractInfo.getId().toString());
			request.setAttribute("contractUploads", contractUploads);
		}
		return SUCCESS;
	}

	/**
	 * 
	 * 根据关键字获取实体数据（会签进度查询编辑按钮）
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String findById() {
		HttpServletRequest request = ApplicationContextUtil.getHttpServletRequest();
		if (contractInfo != null && contractInfo.getId() != null && contractInfo.getId() != 0) {
			contractInfo = (P) baseService.findById(contractInfo.getId());
			Criterion cond1 = Restrictions.eq("contract", contractInfo);
			contractRecords = contractRecordService.findBy(cond1);
			Set set = new HashSet();
			set.add(contractInfo.getCreator());
			Map map = new HashMap();
			map.put("name", contractInfo.getCreator());
			processors = new ArrayList();
			processors.add(map);
			String creator;
			for (int i = 0; i < contractRecords.size(); i++) {
				creator = contractRecords.get(i).getCreator();
				if (!set.contains(creator)) {
					set.add(creator);
					map = new HashMap();
					map.put("name", creator);
					processors.add(map);
				}
			}
		}
		init();

		if ("1".equals(flag)) {
			if (contractInfo != null && contractInfo.getSignCode() != null && !contractInfo.getSignCode().equals("")) {
				actContract = new ActContract();
				if (actContract != null) {
					openContractLink("modify");
					this.actContract.setContractID(projectService.findIdBySigncode(contractInfo.getSignCode()));
				}
			}
			return "countersigned";
		} else if ("2".equals(flag)) {
			contractInfo.setPotency(contractInfo.getPotency());
			if (contractInfo != null && contractInfo.getSignCode() != null && !contractInfo.getSignCode().equals("")) {
				actContract = new ActContract();
				if (actContract != null) {
					openContractLink("modify");
					this.actContract.setContractID(projectService.findIdBySigncode(contractInfo.getSignCode()));
				}
			}
			
			List<ContractRemind> listRemind = getContractRemindService().getContractRemindDao().findListByContractId(contractInfo.getId().toString());
			
			if(listRemind==null||listRemind.size()<=0){
				listRemind=new ArrayList<ContractRemind>();
				for (int i = 0; i < 5; i++) {
					ContractRemind remind = new ContractRemind();
					remind.setContractId(contractInfo.getId().toString());
					remind.setCondTag(String.valueOf(i + 1));
					remind.setTimeType("01");
					getContractRemindService().getContractRemindDao().save(remind);
					listRemind.add(remind);
				}
			}
			
			request.setAttribute("listRemind", listRemind);
			return "archive";
		} else {
			return SUCCESS;
		}
	}

	/**
	 * 获取分页数据
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String findByPage() {
		// 如果第一次装置，默认参数
		if (pageControl == null) {
			pageControl = new PageControl();
		}
		HashMap<String, Object> conds = super.getConds();
		if (conds == null) {
			conds = new HashMap<String, Object>();
		}
		conds.put("submitTime", "null");
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		List<UserResource> modelMenus = ApplicationContextUtil.getUserContextObject().getUserResources();
		boolean searchAll = false;
		for (UserResource ur : modelMenus) {//
			// System.out.println(ur.getKey());
			if (ur.getKey().equals("OBJ_CONTRACT_MAN")) {
				searchAll = true;
				break;
			}
		}
		if (!searchAll) {
			conds.put("creator", currUser.getUserID());
			// conds.put("creator", currUser.getPerson().getName());
		}
		super.setConds(conds);
		pageControl = baseService.findByPage(combineCond(), pageControl.getPageNo(), pageControl.getPageSize());
		init();
		return SUCCESS;
	}

	/**
	 * 
	 * 显示下一办理人的记录
	 * 
	 * @return
	 */
	public String findEdByPage() {
		// 如果第一次装置，默认参数
		if (pageControl == null) {
			pageControl = new PageControl();
		}
		HashMap<String, Object> conds = super.getConds();
		if (conds == null) {
			conds = new HashMap<String, Object>();
		}
		conds.put("status", "0");
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		if (currUser != null) {
			if (getContractInfoService().getContractInfoDAO().isManage(currUser.getPersonID()) == false) {
				conds.put("nextUser", "[" + currUser.getUserID() + "]");
			}
			super.setConds(conds);
		}
		pageControl = baseService.findByPage(combineCond(), pageControl.getPageNo(), pageControl.getPageSize());
		init();
		return SUCCESS;
	}

	/**
	 * 构造参数，转入合同管理系统页面 TODO 请输入方法说明
	 * 
	 * @param act：create：新增的，
	 *            modify：修改或查看
	 */
	public void openContractLink(String act) {
		if (actContract != null) {
			ActionContext ctx = ActionContext.getContext();
			HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
			User user = ((UserContext) request.getSession().getAttribute("LOGINUSER_CONTEXT")).getCurrUser();
			ActContract aTmp = projectService.findCUserInfoById(user.getUserID());
			if (aTmp != null) {
				actContract = aTmp;
			}
			// 查找所在部门
			Criterion cond1 = Restrictions.eq("person", user.getPerson());
			List<OrgRelaPerson> orps = orgRelaPersonService.findBy(cond1);
			if (orps != null && orps.size() > 0) {
				OrgRelaPerson orp = orps.get(0);
				actContract.setCurrDept(orp.getOrganization().getName());
			}
			actContract.setAct(act);
			actContract.setUserId(user.getUserID());

		}
	}

	/**
	 * 
	 * 显示会签进度及版本查询
	 * 
	 * @return
	 */
	public String findCountersignedByPage() {
		// 如果第一次装置，默认参数
		if (pageControl == null) {
			pageControl = new PageControl();
		}
		HashMap<String, Object> conds = super.getConds();
		if (conds == null) {
			conds = new HashMap<String, Object>();
		}
		conds.put("status", "1");
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		if (currUser != null) {
			if (getContractInfoService().getContractInfoDAO().isManage(currUser.getPersonID()) == false) {
				conds.put("nextUser", "[" + currUser.getUserID() + "]");
			}
		}
		super.setConds(conds);
		pageControl = baseService.findByPage(combineCond(), pageControl.getPageNo(), pageControl.getPageSize());
		init();
		return SUCCESS;
	}

	/**
	 * 
	 * 显示归档合同的记录
	 * 
	 * @return
	 */
	public String listArchiveCountersigned() {
		HttpServletRequest request = ApplicationContextUtil.getHttpServletRequest();
		// 如果第一次装置，默认参数
		if (pageControl == null) {
			pageControl = new PageControl();
		}
		HashMap<String, Object> conds = super.getConds();
		if (conds == null) {
			conds = new HashMap<String, Object>();
		}
		conds.put("status", "2");
		/**
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		if (currUser != null) {
			if (getContractInfoService().getContractInfoDAO().isManage(currUser.getPersonID()) == false) {
				conds.put("nextUser", "[" + currUser.getUserID() + "]");
			}
		}**/
		boolean isMange=false;
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		
		if (currUser != null) {
			isMange=getContractInfoService().getContractInfoDAO().isManage(currUser.getPersonID());
			
		}
		
		request.setAttribute("currUser", currUser.getUserID());
		request.setAttribute("isMange", isMange);
		String orderBy = request.getParameter("orderBy");
		if (orderBy != null && !"".equals(orderBy)) {
			request.setAttribute("orderBy", orderBy);
		}
		super.setConds(conds);
		// pageControl = baseService.findByPage(combineCond(), pageControl
		// .getPageNo(), pageControl.getPageSize());
		pageControl = getContractInfoService().findByPageView(combineCond(), pageControl.getPageNo(), pageControl.getPageSize(), orderBy);
		init();
		return SUCCESS;
	}

	/**
	 * 导出excel
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String export() {
		HttpServletRequest request = ApplicationContextUtil.getHttpServletRequest();
		HttpServletResponse response = ApplicationContextUtil.getHttpServletResponse();
		// 如果第一次装置，默认参数

		HashMap<String, Object> conds = super.getConds();
		if (conds == null) {
			conds = new HashMap<String, Object>();
		}
		conds.put("status", "2");
		/**
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		if (currUser != null) {
			if (getContractInfoService().getContractInfoDAO().isManage(currUser.getPersonID()) == false) {
				conds.put("nextUser", "[" + currUser.getUserID() + "]");
			}
		}**/
		super.setConds(conds);
		List<VContractInfo> list = getContractInfoService().getContractInfoDAO().findByView(combineCond());
		out(request, response, list);
		// System.out.println("//////导出条数："+list.size());
		return null;
	}

	@SuppressWarnings("deprecation")
	public void out(HttpServletRequest request, HttpServletResponse response, List<VContractInfo> list) {
		try {
			// open file.
			// String load=request.getRealPath("tmp");
			response.setContentType("application/stream;charset=UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode("合同归档.xls", "UTF-8") + "\"");
			OutputStream os = response.getOutputStream();
			WritableWorkbook book = Workbook.createWorkbook(os);

			String[] headName = new String[] { "合同名称", "合同正式编号", "会签编号", "产品类别	", "合同状态", "甲方", "乙方", "丙方", "合作内容", "合作内容简要说明", "合作模式", "合作模式具体说明", "合同生效日期", "合同终止日期", "对方联系人", "对方联系电话",
					"顺延合同的终止日期	", "备注" };
			WritableSheet sheet = book.createSheet("Sheet_1", 0);
			for (int i = 0; i < headName.length; i++) {
				Label label = new Label(i, 0, headName[i]);
				sheet.addCell(label);
			}
			for (int i = 0; i < list.size(); i++) {
				int j = 0;
				//VContractInfo contractInfo = (VContractInfo) list.get(i);
				ContractInfo contractInfo = (ContractInfo) list.get(i);
				
				Label label = new Label(j++, i + 1, contractInfo.getContractName());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getSerial());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getSignCode());
				sheet.addCell(label);
				if (contractInfo.getContractType() == null) {
					label = new Label(j++, i + 1, "");
				} else {
					label = new Label(j++, i + 1, contractInfo.getContractType().getName());
				}
				sheet.addCell(label);
				String status = contractInfo.getStatus();
				if (status == null || "".equals(status)) {
					label = new Label(j++, i + 1, "");
					sheet.addCell(label);
				} else if ("0".equals(status)) {
					label = new Label(j++, i + 1, "上传");
					sheet.addCell(label);
				} else if ("1".equals(status)) {
					label = new Label(j++, i + 1, "会签");
					sheet.addCell(label);
				} else if ("2".equals(status)) {
					label = new Label(j++, i + 1, "归档");
					sheet.addCell(label);
				}

				label = new Label(j++, i + 1, "");// 甲方
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getSignatoriesName());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getThirdName());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getHezuoContent());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getHezuoContentInfo());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getHezuoMode());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getHezuoModeInfo());
				sheet.addCell(label);
				Date date = contractInfo.getEffectTime();
				if (date == null) {
					label = new Label(j++, i + 1, "");
					sheet.addCell(label);
				} else {
					label = new Label(j++, i + 1, DateUtil.dateToStr(contractInfo.getEffectTime(), "yyyy-MM-dd"));
					sheet.addCell(label);
				}
				date = contractInfo.getMaturityTime();
				if (date == null) {
					label = new Label(j++, i + 1, "");
					sheet.addCell(label);
				} else {
					label = new Label(j++, i + 1, DateUtil.dateToStr(contractInfo.getMaturityTime(), "yyyy-MM-dd"));
					sheet.addCell(label);
				}
				label = new Label(j++, i + 1, contractInfo.getContact());
				sheet.addCell(label);
				label = new Label(j++, i + 1, contractInfo.getContactTel());
				sheet.addCell(label);
				date = contractInfo.getPostponeTime();
				if (date == null) {
					label = new Label(j++, i + 1, "");
					sheet.addCell(label);
				} else {
					label = new Label(j++, i + 1, DateUtil.dateToStr(contractInfo.getPostponeTime(), "yyyy-MM-dd"));
					sheet.addCell(label);
				}
				label = new Label(j++, i + 1, contractInfo.getNotes());
				sheet.addCell(label);
			}

			book.write();

			book.close();
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 组合查询条件
	 * 
	 * @return
	 */

	@SuppressWarnings("unchecked")
	public Criterion combineCond() {
		Criterion cond = null;
		if (super.getConds() != null) {
			// 遍历参数表
			Iterator i = super.getConds().entrySet().iterator();
			while (i.hasNext()) {
				Entry entry = (Entry) i.next();
				String key = (String) entry.getKey();
				if (super.getConds().get(key) != null && !StringUtils.isEmpty(super.getConds().get(key).toString())) {
					// 根据实际情况做处理
					Criterion temp = null;
					if (key.equalsIgnoreCase("contractName")) {
						temp = Restrictions.like(key, "%" + super.getConds().get(key).toString().trim() + "%");
					} else if (key.equalsIgnoreCase("serial")) {
						temp = Restrictions.like(key, "%" + super.getConds().get(key).toString().trim() + "%");
					} else if (key.equalsIgnoreCase("nextUser")) {
						temp = Restrictions.like(key, "%" + super.getConds().get(key).toString().trim() + "%");
					} else if (key.equalsIgnoreCase("signatoriesName")) {
						temp = Restrictions.like(key, "%" + super.getConds().get(key).toString().trim() + "%");
					} else if (key.equalsIgnoreCase("effectTimeBegin")) {
						temp = Restrictions.ge("effectTime", DateUtil.strToDate(super.getConds().get(key).toString(), "yyyy-MM-dd"));

					} else if (key.equalsIgnoreCase("effectTimeEnd")) {
						temp = Restrictions.le("effectTime", DateUtil.strToDate(super.getConds().get(key).toString(), "yyyy-MM-dd"));

					} else if (key.equalsIgnoreCase("postponeTimeBegin")) {
						temp = Restrictions.ge("postponeTime", DateUtil.strToDate(super.getConds().get(key).toString(), "yyyy-MM-dd"));

					} else if (key.equalsIgnoreCase("postponeTimeEnd")) {
						temp = Restrictions.le("postponeTime", DateUtil.strToDate(super.getConds().get(key).toString(), "yyyy-MM-dd"));

					} else if (key.equalsIgnoreCase("submitTime")) {
						if (super.getConds().get(key).equals("null")) {
							temp = Restrictions.isNull(key);
						} else {
							temp = Restrictions.isNotNull(key);
						}
					} else if (key.equalsIgnoreCase("filingTime")) {
						if (super.getConds().get(key).equals("null")) {
							temp = Restrictions.isNull(key);
						} else {
							temp = Restrictions.isNotNull(key);
						}
					} else if (key.equalsIgnoreCase("contractType.id")) {
						temp = Restrictions.eq(key, Integer.parseInt(super.getConds().get(key).toString()));
					} else {
						temp = Restrictions.eq(key, super.getConds().get(key));
					}

					if (cond == null) {
						cond = temp;
					} else {
						cond = Restrictions.and(cond, temp);
					}
				}
			}
		}
		return cond;
	}

	/**
	 * 提交并归档
	 * 
	 * @return
	 */
	public String archiveCountersigned() {
		if (contractInfo != null && contractInfo.getFilingTime() == null) {
			contractInfo.setFilingTime(baseService.getCurrSysdate());
		}
		String path = Constants.SERVER_PATH + "/upload/";
		contractInfo.setStatus("2");
		return this.saveOrUpdate();
	}

	public String contractDetail() {
		openContractLink("modify");
		this.actContract.setSignCode("");
		return SUCCESS;
	}

	/**
	 * 提交并转入会签
	 * 
	 * @return
	 */
	public String saveCountersigned() {
		if (contractInfo != null && contractInfo.getSubmitTime() == null) {
			contractInfo.setSubmitTime(baseService.getCurrSysdate());
		}
		contractInfo.setStatus("1");
		openContractLink("create");
		return this.saveOrUpdate();
	}

	public void saveOrUpdateRemind() {
		HttpServletRequest request = ApplicationContextUtil.getHttpServletRequest();
		List<ContractRemind> listRemind = getContractRemindService().getContractRemindDao().findListByContractId(contractInfo.getId().toString());
		List<ContractRemind> nListRemind = new ArrayList<ContractRemind>();
		int count=listRemind.size();
		String startTag=null;
		Date currentDate=new Date();
		for (int i = 0; i < count; i++) {
			ContractRemind remind = listRemind.get(i);
			startTag="remind" + remind.getCondTag();
			String condNote = request.getParameter(startTag + ".condNote");
			if (condNote != null && !"".equals(condNote)) {
				remind.setCondNote(condNote);
			}
			
			
			
			String timeType = request.getParameter(startTag + ".timeType");
			if (timeType != null && !"".equals(timeType)) {
				remind.setTimeType(timeType);
			}
			
			if("01".equals(timeType)){
				String condTime = request.getParameter(startTag + ".condTime");
				if (condTime != null && !"".equals(condTime)) {
					remind.setCondTime(DateUtil.strToDate(condTime, "yyyy-MM-dd"));
				}
				
				remind.setNextTime(remind.getCondTime());
				
				remind.setStartTime(null);
				remind.setEndTime(null);
				remind.setMonDay(null);
			}else{
				String startTime = request.getParameter(startTag + ".startTime");
				if (startTime != null && !"".equals(startTime)) {
					remind.setStartTime(DateUtil.strToDate(startTime, "yyyy-MM-dd"));
				}else{
					remind.setStartTime(currentDate);
				}
				Date maxStartTime=currentDate;
				if(remind.getStartTime().after(currentDate)){
					maxStartTime=remind.getStartTime();
				}
				//
				String endTime = request.getParameter(startTag + ".endTime");
				if (endTime != null && !"".equals(endTime)) {
					remind.setEndTime(DateUtil.strToDate(endTime, "yyyy-MM-dd"));
				}else{
					remind.setEndTime(contractInfo.getPostponeTime());
				}
				int monDayInt=1;
				String monDay = request.getParameter(startTag + ".monDay");
				if (monDay != null && !"".equals(monDay)) {
					monDayInt=Integer.valueOf(monDay);
				}
				
				remind.setCondTime(null);
				//计算下一次提醒的时间
				Calendar ca=Calendar.getInstance();
				ca.setTime(maxStartTime);
				ca.set(Calendar.DAY_OF_MONTH, monDayInt);
				ca.set(Calendar.HOUR_OF_DAY, 23);
				ca.set(Calendar.MINUTE, 0);
				ca.set(Calendar.SECOND, 0);
				ca.set(Calendar.MILLISECOND, 0);
				
				Date tmpDate=ca.getTime();
				if(maxStartTime.after(tmpDate)){
					ca.add(Calendar.MONTH, 1);
				}
				ca.set(Calendar.HOUR_OF_DAY, 0);
				
				//比对是修改了提醒周期的时间
				if(remind.getMonDay()!=null&&remind.getMonDay()!=monDayInt){
					remind.setNextTime(ca.getTime());
				}
				//跟原来时间比较
				if(remind.getNextTime()!=null){
					if(ca.getTime().after(remind.getNextTime())){
						remind.setNextTime(ca.getTime());
					}
				}else{
					remind.setNextTime(ca.getTime());
				}
				//跟结束时间比较
				if(remind.getEndTime()!=null){
					if(remind.getEndTime().before(ca.getTime())){
						remind.setNextTime(null);
					}
				}
				remind.setMonDay(Integer.valueOf(monDayInt));
			}
			nListRemind.add(remind);
		}
		getContractRemindService().getContractRemindDao().saveRemind(nListRemind, contractInfo.getId().toString());
	}

	/**
	 * 新增或修改数据
	 * 
	 * @return
	 */

	@SuppressWarnings("unchecked")
	public String saveOrUpdate() {
		HttpServletRequest request = ApplicationContextUtil.getHttpServletRequest();
		// 设置操作人
		User currUser = ApplicationContextUtil.getUserContextObject().getCurrUser();
		if (contractInfo != null && contractInfo.getCreateTime() == null) {
			contractInfo.setCreateTime(baseService.getCurrSysdate());
		}
		if (contractInfo != null && (contractInfo.getStatus() == null || "".equals(contractInfo.getStatus()))) {
			contractInfo.setStatus("0");
		}
		if (contractInfo.getPostponeTime() == null && contractInfo.getMaturityTime() != null) {
			contractInfo.setPostponeTime(contractInfo.getMaturityTime());
		}
		contractInfo.setNextUser(processNextUser(contractInfo.getNextUser(), currUser.getUserID()));

		if (contractInfo.getCreatorName() == null || "".equals(contractInfo.getCreatorName())) {
			contractInfo.setCreatorName(currUser.getPerson().getName());
		}
		baseService.saveOrUpdate(contractInfo);
		String isRemind = request.getParameter("isRemind");
		if ("true".equals(isRemind)) {
			saveOrUpdateRemind();
		}
		// 文件路径
		String contextPath = ServletActionContext.getServletContext().getRealPath("/");
		String saveDirectory = contextPath + PropertiesUtil.readValue("/poc-ftp.properties", "ftp.path");
		String contractUploadDirectory = getConfigBean().getContractUploadDirectory();
		saveDirectory = contractUploadDirectory;
		//当前年月
		Date date = new Date();
		String monthFile = DateUtil.dateTimeToStr(date, "yyyy-MM");
		System.out.println(monthFile);
		// 保存附件
		if (uploads != null) {
			int i = 0;
			for (i = 0; i < uploads.size(); i++) {
				try {
					File file = uploads.get(i);
					byte[] result = new byte[BUFFER_SIZE];
					result = FileUtils.readFileToByteArray(file);

					String fileName = this.fileNames.get(i);
					String fullName = fileName;
					String name = fullName.substring(0, fullName.indexOf("."));
					String prefix = fullName.substring(fullName.indexOf(".") + 1, fullName.length());
					Attach attach = new Attach();
					attach.setContent(result);
					attach.setFileType("FILE");
					attach.setFullName(fullName);
					attach.setName(name);
					attach.setPrefix(prefix);
					attach.setRefEntity(contractInfo.getClass().getName());
					attach.setRefEntityID(contractInfo.getId().toString());
					attach.setIsPublish(0);// 默认为不发布

					String dateName = String.valueOf(new Date().getTime());
					String realName = dateName + "." + prefix;
					// 保存绝对路径
					String saveFilePath = saveDirectory + monthFile + "/" + realName;
					File toFile = new File(saveFilePath);

					FileUtils.copyFile(file, toFile);

					//新的文件存储附件方式删除附件保存功能
					ContractUpload contractUpload = new ContractUpload();
					contractUpload.setContractInfoId(contractInfo.getId().toString());
					contractUpload.setFileName(fileName);
					contractUpload.setRealName(realName);
					contractUpload.setMonthFile(monthFile);
					FileUtils.forceDelete(file);
					getContractInfoService().getAttachDAO().getHibernateTemplate().save(contractUpload);

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		String[] delIDs = request.getParameterValues("delIDs");// 待删除的附件id数组
		//旧的数据库存储附件方式删除附件功能
		//		if (delIDs != null) {
		//			for (int i = 0; i < delIDs.length; i++) {
		//				String delId = delIDs[i];
		//				attachService.deleteBy(new Attach(), "id", delId);
		//			}
		//		}
		//新的文件存储附件方式删除附件功能
		if (delIDs != null) {
			getContractInfoService().deleteContractUploads(delIDs, saveDirectory);
		}
		if (contractRecord != null && !"".equals(contractRecord.getAdvice())) {
			contractRecord.setCreateTime(contractRecordService.getCurrSysdate());
			contractRecord.setContract(contractInfo);
			if (currUser != null) {

				contractRecord.setCreator(currUser.getUserID());
				contractRecord.setCreatorName(currUser.getPerson().getName());
			}
			contractRecordService.saveOrUpdate(contractRecord);
		}
		if (flag != null && "counter".equals(flag)) {
			return "counter";
		} else if (flag != null && "archive".equals(flag)) {
			return "archive";
		}
		return SUCCESS;
	}

	/**
	 * 文件拷贝
	 * 
	 * @param f1
	 * @param f2
	 * @return
	 * @throws Exception
	 */
	public long copyFile(File fromFile, File toFile) throws Exception {
		long time = new Date().getTime();
		int length = 2097152;
		FileInputStream in = new FileInputStream(fromFile);
		RandomAccessFile out = new RandomAccessFile(toFile, "rw");
		FileChannel inC = in.getChannel();
		MappedByteBuffer outC = null;
		MappedByteBuffer inbuffer = null;
		byte[] b = new byte[length];
		while (true) {
			if (inC.position() == inC.size()) {
				inC.close();
				outC.force();
				out.close();
				return new Date().getTime() - time;
			}
			if ((inC.size() - inC.position()) < length) {
				length = (int) (inC.size() - inC.position());
			} else {
				length = 20971520;
			}
			b = new byte[length];
			inbuffer = inC.map(MapMode.READ_ONLY, inC.position(), length);
			inbuffer.load();
			inbuffer.get(b);
			outC = out.getChannel().map(MapMode.READ_WRITE, inC.position(), length);
			inC.position(b.length + inC.position());
			outC.put(b);
			outC.force();
		}
	}

	/**
	 * 
	 * @param nextUser
	 * @param curUser
	 * @return
	 */
	public String processNextUser(String nextUser, String curUser) {
		String[] nextTo = this.getContextObjects("nextTo");
		// if (nextTo.length == 0)
		// {
		// return nextUser;
		// }
		Set strSet = new HashSet();
		strSet.add(curUser);
		if (nextUser != null && !"".equals(nextUser)) {
			nextUser = nextUser.replace("][", ",");
			nextUser = nextUser.replace("]", "");
			nextUser = nextUser.replace("[", "");
			String[] nextUsers = nextUser.split(",");
			CollectionUtils.addAll(strSet, nextUsers);
		}
		for (int i = 0; i < nextTo.length; i++) {
			if (nextTo[i] != null && !"".equals(nextTo[i])) {
				strSet.add(nextTo[i]);
			}
		}

		Iterator it = strSet.iterator();
		String temp = "";
		String ret = "";
		while (it.hasNext()) {
			temp = it.next().toString();
			if (!"".equals(temp)) {
				ret += "[" + temp + "]";
			}
		}
		return ret;
	}

	/**
	 * 
	 * 删除操作
	 * 
	 * @return
	 */
	public String remove() {
		baseService.remove(contractInfo);
		if ("1".equals(flag)) {
			return "countersigned";
		} else if ("2".equals(flag)) {
			return "archive";
		} else {
			return SUCCESS;
		}
	}

	public P getContractInfo() {
		return contractInfo;
	}

	public void setContractInfo(P contractInfo) {
		this.contractInfo = contractInfo;
	}

	/**
	 * 获取附件列表数据
	 * 
	 * @return the attachs
	 */
	public List<Attach> getAttachs() {
		return attachs;
	}

	/**
	 * 设置附件列表数据
	 * 
	 * @param attachs
	 *            the attachs to set
	 */
	public void setAttachs(List<Attach> attachs) {
		this.attachs = attachs;
	}

	/**
	 * 获取附件服务
	 * 
	 * @return the attachService
	 */
	public AttachService getAttachService() {
		return attachService;
	}

	/**
	 * 设置附件服务
	 * 
	 * @param attachService
	 *            the attachService to set
	 */
	public void setAttachService(AttachService attachService) {
		this.attachService = attachService;
	}

	/**
	 * 查看附件
	 * 
	 * @return
	 */
	public String showFile() {
		String contextPath = ServletActionContext.getServletContext().getRealPath("/");
		String saveDirectory = contextPath + PropertiesUtil.readValue("/poc-ftp.properties", "ftp.path");
		saveDirectory = getConfigBean().getContractUploadDirectory();//获取文件保存路径
		ActionContext ctx = ActionContext.getContext();
		HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);
		String id = request.getParameter("id");
		ContractUpload contractUpload = getContractInfoService().getContractInfoDAO().getContractUpload(id);
		String fileName = contractUpload.getFileName();//文件原名
		String realName = contractUpload.getRealName();//文件时间串名
		String monthFile = contractUpload.getMonthFile();//文件所在文件夹
		String saveFilePath = saveDirectory + monthFile + "/" + realName;
		// FileUtils.copyFile(file, new File(saveFilePath));
		response.setContentType("application/x-download");// 设置为下载application/x-download
		try {
			response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GBK"), "iso8859-1"));
			byte[] result = new byte[BUFFER_SIZE];
			result = FileUtils.readFileToByteArray(new File(saveFilePath));
			write(response.getOutputStream(), result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 输出文件内容
	 * @param os
	 * @param content
	 */
	private void write(OutputStream os, byte[] content) {
		try {
			os.write(content);
			os.flush();
		} catch (IOException ex) {
			throw new RuntimeException(ex);
		}
	}

	public List<String> getUploadFileName() {
		return fileNames;
	}

	public void setUploadFileName(List<String> fileNames) {
		this.fileNames = fileNames;
	}

	public List<File> getUpload() {
		return uploads;
	}

	public void setUpload(List<File> uploads) {
		this.uploads = uploads;
	}

	public void setUploadContentType(List<String> contentTypes) {
		this.uploadContentTypes = contentTypes;
	}

	public List<String> getUploadContentType() {
		return this.uploadContentTypes;
	}

	public ContractRecordService getContractRecordService() {
		return contractRecordService;
	}

	public void setContractRecordService(ContractRecordService contractRecordService) {
		this.contractRecordService = contractRecordService;
	}

	public ContractRecord getContractRecord() {
		return contractRecord;
	}

	public void setContractRecord(ContractRecord contractRecord) {
		this.contractRecord = contractRecord;
	}

	public List<ContractRecord> getContractRecords() {
		return contractRecords;
	}

	public void setContractRecords(List<ContractRecord> contractRecords) {
		this.contractRecords = contractRecords;
	}

	public DictService getDictService() {
		return dictService;
	}

	public void setDictService(DictService dictService) {
		this.dictService = dictService;
	}

	@SuppressWarnings("unchecked")
	public DictTypeService getDictTypeService() {
		return dictTypeService;
	}

	@SuppressWarnings("unchecked")
	public void setDictTypeService(DictTypeService dictTypeService) {
		this.dictTypeService = dictTypeService;
	}

	public List<Dict> getContractTypes() {
		return contractTypes;
	}

	public void setContractTypes(List<Dict> contractTypes) {
		this.contractTypes = contractTypes;
	}

	public List getProcessors() {
		return processors;
	}

	public void setProcessors(List processors) {
		this.processors = processors;
	}

	public String getFlag() {
		return flag;
	}

	public void setFlag(String flag) {
		this.flag = flag;
	}

	public OrgRelaPersonService getOrgRelaPersonService() {
		return orgRelaPersonService;
	}

	public void setOrgRelaPersonService(OrgRelaPersonService orgRelaPersonService) {
		this.orgRelaPersonService = orgRelaPersonService;
	}

	public ActContract getActContract() {
		return actContract;
	}

	public void setActContract(ActContract actContract) {
		this.actContract = actContract;
	}

	public File getFile1() {
		return file1;
	}

	public void setFile1(File file1) {
		this.file1 = file1;
	}

	public File getFile2() {
		return file2;
	}

	public void setFile2(File file2) {
		this.file2 = file2;
	}

	public ProjectService getProjectService() {
		return projectService;
	}

	public void setProjectService(ProjectService projectService) {
		this.projectService = projectService;
	}

	public ContractInfoService getContractInfoService() {
		return contractInfoService;
	}

	public void setContractInfoService(ContractInfoService contractInfoService) {
		this.contractInfoService = contractInfoService;
	}

	public ContractRemindService getContractRemindService() {
		return contractRemindService;
	}

	public void setContractRemindService(ContractRemindService contractRemindService) {
		this.contractRemindService = contractRemindService;
	}

	public List<ContractUpload> getContractUploads() {
		return contractUploads;
	}

	public void setContractUploads(List<ContractUpload> contractUploads) {
		this.contractUploads = contractUploads;
	}

	public static void main(String[] args) {
		Date currentDate=new Date();
		Calendar ca=Calendar.getInstance();
		ca.setTime(currentDate);
		ca.set(Calendar.DAY_OF_MONTH, 3);
		Date tmpDate=ca.getTime();
		if(currentDate.after(tmpDate)){
			ca.add(Calendar.MONTH, 1);
		}
		System.out.println(ca.getTime());
	}
}
